import './index.scss'

import * as THREE from "three"
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";

const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 1000)
camera.position.set(1, 5, 8)
const renderer = new THREE.WebGLRenderer()
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)

// 地表格
const grid = new THREE.GridHelper(500, 100, 0xffffff, 0xffffff)
grid.material.opacity = 0.5
grid.material.depthWrite = false
grid.material.transparent = true
scene.add(grid)

// 地板
const geoFloor = new THREE.PlaneGeometry( 15, 15 );
const matFloor = new THREE.MeshPhongMaterial({color: 0xffffff});
matFloor.needsUpdate = true;
const mshFloor = new THREE.Mesh( geoFloor, matFloor );
mshFloor.rotation.x = - Math.PI / 2;
mshFloor.receiveShadow = true;
// mshFloor.castShadow = true;
const bgFloor = new THREE.PlaneGeometry(2, 1)
const bgmatFloor = new THREE.MeshPhongMaterial({color: 0xffffff});
const textureLoader = new THREE.TextureLoader();
scene.add( mshFloor );
textureLoader.loadAsync('./image/hardwood2_diffuse.jpg').then(texture => {
    bgmatFloor.map = texture;
    bgmatFloor.needsUpdate = true;
    const BGmshFloor = new THREE.Mesh( bgFloor, bgmatFloor );
    BGmshFloor.position.y = .47
    BGmshFloor.position.z = -.45
    BGmshFloor.receiveShadow = false;
    scene.add( BGmshFloor );
});
// 灯光
const ambientLight = new THREE.AmbientLight('#fff', .8)
scene.add(ambientLight)

// 创建平行光
const directionalLight = new THREE.DirectionalLight('#fff', 3)
directionalLight.position.set(-1, 1, 1)
directionalLight.castShadow = true
directionalLight.visible = false
scene.add(directionalLight)
// 创建平行光辅助线
const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight, 1)
directionalLightHelper.visible = true
scene.add(directionalLightHelper)

const light = new THREE.SpotLight(0xffffff, 10, 100, Math.PI / 6, 0.25, 1)
light.position.set(0, 2, 0)
light.castShadow = true
//告诉平行光需要开启阴影投射
// light.shadow.mapSize.width = 1024
// light.shadow.mapSize.height = 1024
//告诉平行光产生阴影的区域
// light.shadow.camera.near = 0.5
light.shadow.camera.visible = true
// 创建平行光辅助线
const spotLightHelper = new THREE.SpotLightHelper(light, 1)
spotLightHelper.visible = true
scene.add(spotLightHelper)
scene.add(light)

// 控制器
const control = new OrbitControls(camera, renderer.domElement)

// 辅助器
// const axesHelper = new THREE.AxesHelper(5);
// scene.add(axesHelper);

// 背景
scene.background = new THREE.Color(0xbbbbbb)

// 预设动画
const clock = new THREE.Clock()
let mixer: THREE.AnimationMixer | null = null;

// GLB加载器
const loader = new GLTFLoader();
loader.load('glb/dance.glb', function (gltf) {
    mixer = new THREE.AnimationMixer(gltf.scene)
    gltf.scene.scale.set(0.8, 0.8, 0.8);
    gltf.scene.position.set(0, 0, 0);
    console.log(gltf);
    scene.add(gltf.scene);
    // const model = gltf.scene;
    console.log(gltf.animations);
    // mixer.clipAction(gltf.animations[0]).play()

    const model = gltf.scene;
    model.traverse((child: any) => {
        if(child.isSkinnedMesh) {
            // console.log('找到 SkinnedMesh:', child.name);
            console.log(child.skeleton.bones);
            setBones(child.skeleton.bones);
        }
    })


})

var index = -1;
var timer: any = 0;
function setBones(bones: any) {
    if(index == 0) return;
    index = 0;
    timer = setInterval(() => {
        if(bones.length <= index) {
            clearInterval(timer);
            return;
        }
        var bone = bones[index];
        bone.position.y += 10; // 向上移动 1 个单位
        bone.position.z += 10; // 向上移动 1 个单位
        bone.position.x += 10; // 向上移动 1 个单位
        // 更新骨骼矩阵，使其变动生效
        bone.updateMatrixWorld(true);
        index++;
    }, 500);
}

function animate() {
    requestAnimationFrame(animate)
    if (mixer) mixer.update(clock.getDelta())
    control.update()
    render();
}

function render() {
    renderer.render(scene, camera)
}

animate();
